package com.qjc.demo.thread.countDownLatch;

import java.util.concurrent.CountDownLatch;

/**
 * @Description:
 * @Author: qjc
 * @Date: 2020/7/17
 */
public class CountDownLatchTest1 {
    /**
     * CountDownLatch和join的区别：
     * 1、调用子线程的join方法后，该线程会一直被阻塞直到子线程运行完毕，而CountDownLatch则使用计数器来
     * 允许子线程运行完毕或者在运行中递减计数，也就是CountDownLatch可以在子线程运行的任何时候让await
     * 方法返回而不一定必须等到线程结束；
     * 2、使用线程池时一般都是直接添加Runnable到线程池，这时候就没有办法再调用线程的join方法了，就是说
     * CountDownLatch相比join方法让我们对线程同步有更灵活的控制。
     */

    public static void main(String[] args) throws InterruptedException {
        final CountDownLatch countDownLatch = new CountDownLatch(2);

        Thread threadA = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("子线程A运行1s");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            try {
                Thread.sleep(2000);
                System.out.println("子线程A又运行了2s");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread threadB = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("子线程B运行1s");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
            try {
                Thread.sleep(2000);
                System.out.println("子线程B又运行了2s");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        threadA.start();
        threadB.start();
        System.out.println("等待子线程运行1s完毕");
        //等待子线程运行完毕
        countDownLatch.await();
        long count = countDownLatch.getCount();


        System.out.println("countDownLatch：" + count + "，所有子线程工作了1s，主线程就可以干其他事儿，不用管子线程后面的运行");

    }

}
